package linear.queue.base;

/**
 * 循环队列(数组实现队列的时候，由于数据搬移操作会影响入队的效率，采用循环队列来去掉数据搬移)
 * 队满条件 (tail + 1) % size == head
 * 实际存的会少一个
 *
 * @author yeyangtao created at 14:12 2020/9/23
 */
public class MyArrayLoopQueue<T> implements MyQueue<T> {
    private final Object[] value;
    private int head = 0;
    private int tail = 0;
    //数组大小
    private int size = 16;

    public MyArrayLoopQueue() {
        value = new Object[size];
    }

    public MyArrayLoopQueue(int size) {
        value = new Object[size];
        this.size = size;
    }

    @Override
    public boolean offer(Object o) {
        //队列满了
        if ((tail + 1) % size == head) return false;
        //未满
        value[tail] = o;
        tail = (tail + 1) % size;
        return true;
    }

    @Override
    public T poll() {
        if (head == tail) return null;
        @SuppressWarnings("unchecked")
        T result = (T) value[head];
        head = (head + 1) % size;
        return result;
    }

    @Override
    public T peek() {
        if (head == tail) return null;
        @SuppressWarnings("unchecked")
        T result = (T) value[head];
        return result;
    }

    @Override
    public boolean isEmpty() {
        return tail - head == 0;
    }

    @Override
    public int size() {
        return tail - head;
    }

    @Override
    public String toString() {
        if (value == null) return "null";
        if (tail - head == 0) return "[]";
        StringBuilder sb = new StringBuilder("[");
        for (int i = head; (i + 1) % size != tail; ) {
            sb.append(value[i].toString());
            i = (i + 1) % size;
            if ((i + 1) % size != tail)
                sb.append(", ");
            else
                sb.append(", ").append(value[i].toString());
        }
        sb.append("]");
        return sb.toString();
    }
}
